package online.flowerinsnow.minecraft.bukkit.manhunt.command;

import online.flowerinsnow.minecraft.bukkit.manhunt.config.ManhuntConfiguration;
import online.flowerinsnow.minecraft.bukkit.manhunt.core.PlayerTeam;
import online.flowerinsnow.minecraft.bukkit.manhunt.core.hunter.OnDead;
import online.flowerinsnow.minecraft.bukkit.manhunt.manager.ITeamManager;
import online.flowerinsnow.minecraft.bukkit.manhunt.manager.IWorldManager;
import online.flowerinsnow.minecraft.bukkit.manhunt.runnable.DelayStartRunnable;
import online.flowerinsnow.minecraft.bukkit.manhunt.runnable.GameTimerRunnable;
import online.flowerinsnow.minecraft.bukkit.manhunt.util.MessageUtils;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import online.flowerinsnow.minecraft.bukkit.manhunt.Manhunt;
import online.flowerinsnow.minecraft.bukkit.manhunt.listener.InvisibleListener;
import online.flowerinsnow.minecraft.bukkit.manhunt.util.CommandUtils;

import java.util.*;

import static online.flowerinsnow.minecraft.bukkit.manhunt.util.CommandUtils.*;

public class CommandManhunt implements TabExecutor {
    @Override
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) {
        if (args.length == 1) {
            if ("clearteam".equalsIgnoreCase(args[0])) {
                Bukkit.getOnlinePlayers().forEach(p -> Manhunt.getTeamManager().setPlayerTeam(p, null));
                sender.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b成功清除所有玩家的队伍"));
                return true;
            } else if ("reload".equalsIgnoreCase(args[0])) {
                if (checkPermission(sender, "manhunt.reload")) return true;
                ManhuntConfiguration.load();
                sender.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b重载成功"));
                return true;
            } else if ("visible".equalsIgnoreCase(args[0])) {
                if (checkPermission(sender, "manhunt.visible")) return true;
                if (!(sender instanceof Player)) {
                    MessageUtils.sendMustBePlayer(sender);
                    return true;
                }
                Player player = (Player) sender;
                if (InvisibleListener.INVISIBLE_PLAYERS.contains(player.getUniqueId())) {
                    InvisibleListener.INVISIBLE_PLAYERS.remove(player.getUniqueId());
                    player.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b已&c关闭&b隐身"));
                    player.setCollidable(true);

                    Bukkit.getOnlinePlayers().forEach(p -> {
                        if (p.getUniqueId() != player.getUniqueId())
                            p.showPlayer(Manhunt.getInstance(), player);
                    });
                } else {
                    InvisibleListener.INVISIBLE_PLAYERS.add(player.getUniqueId());
                    player.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b已&a开启&b隐身"));
                    player.setCollidable(false);

                    Bukkit.getOnlinePlayers().forEach(p -> {
                        if (p.getUniqueId() != player.getUniqueId())
                            p.hidePlayer(Manhunt.getInstance(), player);
                    });
                }
                return true;
            } else if ("specialmobs".equalsIgnoreCase(args[0])) {
                if (CommandUtils.checkPermission(sender, "manhunt.pluginsettings")) return true;
                ManhuntConfiguration.Fun.specialmobs = !ManhuntConfiguration.Fun.specialmobs;
                ManhuntConfiguration.save();
                if (ManhuntConfiguration.Fun.specialmobs) {
                    sender.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b已&a开启&b特殊怪物"));
                } else {
                    sender.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b已&c关闭&b特殊怪物"));
                }
                return true;
            } else if ("fastmine".equalsIgnoreCase(args[0])) {
                if (CommandUtils.checkPermission(sender, "manhunt.pluginsettings")) return true;
                ManhuntConfiguration.Fun.fastMine = !ManhuntConfiguration.Fun.fastMine;
                ManhuntConfiguration.save();
                if (ManhuntConfiguration.Fun.fastMine) {
                    sender.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b已&a开启&b快速挖矿"));
                } else {
                    sender.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b已&c关闭&b快速挖矿"));
                }
                return true;
            } else if ("randomrunner".equalsIgnoreCase(args[0])) {
                if (CommandUtils.checkPermission(sender, "manhunt.jointeam")) return true;
                ArrayList<Player> freePlayer = new ArrayList<>();
                Bukkit.getOnlinePlayers().forEach(p -> {
                    if (Manhunt.getTeamManager().getPlayerTeam(p) == null) freePlayer.add(p);
                });
                if (freePlayer.isEmpty()) {
                    sender.sendMessage(MessageUtils.parseColor("&7[&c×&7]&c没有还未分配阵营的玩家了"));
                    return true;
                }
                Player selected = freePlayer.get(Manhunt.RAND.nextInt(freePlayer.size()));
                Manhunt.getTeamManager().setPlayerTeam(selected, PlayerTeam.RUNNER);
                return true;
            } sendUsage(sender);
        } else if (args.length == 2) {
            // /mh world
            if ("arena".equalsIgnoreCase(args[0])) {
                IWorldManager worldManager = Manhunt.getWorldManager();
                switch (args[1].toLowerCase()) {
                    case "create" -> {
                        if (checkPermission(sender, "manhunt.arena.create")) return true;
                        if (worldManager.hasArena()) {
                            sender.sendMessage(MessageUtils.parseColor("&7[&c×&7]&c竞技场已存在"));
                        } else {
                            createArena(sender);
                        }
                    }
                    case "delete" -> {
                        if (checkPermission(sender, "manhunt.arena.delete")) return true;
                        deleteArena(() -> sender.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b世界删除完毕")));
                    }
                    case "recreate" -> {
                        if (checkPermission(sender, "manhunt.arena,recreate")) return true;
                        deleteArena(() -> createArena(sender));
                    }
                    default -> sendUsage(sender);
                }
            } else if ("timer".equalsIgnoreCase(args[0])) {
                if ("start".equalsIgnoreCase(args[1])) {
                    if (checkPermission(sender, "manhunt.timer.start")) return true;
                    if (GameTimerRunnable.isStart()) {
                        sender.sendMessage(MessageUtils.parseColor("&7[&c×&7]&c计时器已经开始"));
                    } else {
                        GameTimerRunnable.start();
                        sender.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b开始计时"));
                    }
                } else if ("stop".equalsIgnoreCase(args[1])) {
                    if (checkPermission(sender, "manhunt.timer.stop")) return true;
                    if (GameTimerRunnable.isStart()) {
                        GameTimerRunnable.stop();
                        sender.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b停止计时"));
                    } else {
                        sender.sendMessage(MessageUtils.parseColor("&7[&c×&7]&c计时器没有开始"));
                    }
                } else {
                    try {
                        GameTimerRunnable.secs = Integer.parseInt(args[1]);
                        sender.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b设置时间成功"));
                    } catch (NumberFormatException e) {
                        sendUsage(sender);
                    }
                }
            } else if ("start".equalsIgnoreCase(args[0])) {
                if (checkPermission(sender, "manhunt.start")) return true;
                if (!Manhunt.getWorldManager().hasArena()) {
                    sender.sendMessage(MessageUtils.parseColor("&7[&c×&7]&c竞技场不存在"));
                    return true;
                }
                int delay;
                try {
                    delay = Integer.parseInt(args[1]);
                } catch (NumberFormatException e) {
                    sender.sendMessage(MessageUtils.parseColor("&7[&c×&7]&e") + args[1] + MessageUtils.parseColor(" &c不是一个正确的数字"));
                    return true;
                }
                if (delay < 0) {
                    DelayStartRunnable.stop();
                    DelayStartRunnable.timer = -1;
                    DelayStartRunnable.setHunterStartInfo();
                    return true;
                }
                GameTimerRunnable.stop();
                GameTimerRunnable.secs = 0;
                //noinspection ConstantConditions
                Manhunt.getTeamManager().getRunners().forEach(p -> p.teleport(Bukkit.getWorld("arena").getSpawnLocation()));
                DelayStartRunnable.start(delay);
                return true;
            } else {
                sendUsage(sender);
            }
        } else if (args.length == 3) {
            switch (args[0].toLowerCase()) {
                case "tpworld":
                    if (checkPermission(sender, "manhunt.tpworld")) return true;
                    Set<Player> players = parseTpWorldPlayer(args[1]);
                    if (players == null) {
                        sender.sendMessage(MessageUtils.parseColor("&7[&c×&7]&c目标玩家不存在"));
                        return true;
                    }
                    World world = Bukkit.getWorld(args[2]);
                    if (world == null) {
                        sender.sendMessage(MessageUtils.parseColor("&7[&c×&7]&c世界不存在"));
                    } else {
                        players.forEach(p -> p.teleport(world.getSpawnLocation()));
                        sender.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b传送完毕"));
                    }
                    break;
                case "jointeam":
                    joinTeam(sender, args[1], new String[] {args[2]});
                    break;
                case "ondead":
                    if ("hunter".equalsIgnoreCase(args[1])) {
                        if (checkPermission(sender, "manhunt.ondead.hunter")) return true;
                        try {
                            ManhuntConfiguration.Hunter.ondead = OnDead.valueOf(args[2].toUpperCase());
                            sender.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b设置成功"));
                        } catch (IllegalArgumentException e) {
                            sender.sendMessage(MessageUtils.parseColor("&7[&c×&7]&c未知的选项: ") + args[2]);
                        }
                    } else if ("runner".equalsIgnoreCase(args[1])) {
                        if (checkPermission(sender, "manhunt.ondead.runner")) return true;
                        try {
                            ManhuntConfiguration.Runner.ondead = online.flowerinsnow.minecraft.bukkit.manhunt.core.runner.OnDead.valueOf(args[2].toUpperCase());
                            sender.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b设置成功"));
                        } catch (IllegalArgumentException e) {
                            sender.sendMessage(MessageUtils.parseColor("&7[&c×&7]&c未知的选项: ") + args[2]);
                        }
                    } else {
                        sender.sendMessage(MessageUtils.parseColor("&7[&c×&7]&c未知的阵营: ") + args[1]);
                    }
                    break;
                default:
                    sendUsage(sender);
                    break;
            }
        } else if (args.length > 3) {
            if ("jointeam".equalsIgnoreCase(args[0])) {
                joinTeam(sender, args[1], Arrays.copyOfRange(args, 2, args.length));
            } else {
                sendUsage(sender);
            }
        } else {
            sendUsage(sender);
        }
        return true;
    }

    @Override
    public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) {
        if (args.length == 1) {
            return subCommandFilter(args[0], "arena", "jointeam", "clearteam", "tpworld", "ondead", "timer", "start", "reload", "visible", "specialmobs", "fastmine", "randomrunner");
        } else if (args.length == 2) {
            switch (args[0].toLowerCase()) {
                case "arena":
                    return subCommandFilter(args[1], "create", "delete", "recreate");
                case "jointeam":
                    return subCommandFilter(args[1], "runner", "hunter", "spectator", "clear");
                case "tpworld":
                    List<String> var1 = new ArrayList<>(Arrays.asList("runner", "hunter", "spectator", "null", "*", "all"));
                    Bukkit.getOnlinePlayers().forEach(p -> var1.add(p.getName()));
                    String[] var2 = new String[var1.size()];
                    var2 = var1.toArray(var2);
                    return subCommandFilter(args[1], var2);
                case "ondead":
                    return subCommandFilter(args[1], "hunter", "runner");
                case "timer":
                    return subCommandFilter(args[1], "start", "stop");
                default:
                    return new ArrayList<>();
            }
        } else if (args.length == 3) {
            switch (args[0].toLowerCase()) {
                case "jointeam":
                    return switch (args[1].toLowerCase()) {
                        case "runner", "hunter", "spectator", "clear" -> playerSubCommandFilter(sender, args[2]);
                        default -> new ArrayList<>();
                    };
                case "tpworld":
                    return switch (args[1].toLowerCase()) {
                        case "runner", "hunter", "spectator", "null", "*" -> worldSubCommandFilter(args[2]);
                        default -> new ArrayList<>();
                    };
                case "ondead":
                    return switch (args[1].toLowerCase()) {
                        case "hunter" -> enumSubCommandFilter(args[2], OnDead.class);
                        case "runner" -> enumSubCommandFilter(args[2], online.flowerinsnow.minecraft.bukkit.manhunt.core.runner.OnDead.class);
                        default -> new ArrayList<>();
                    };
            }
        } else if (args.length > 3) {
            if ("jointeam".equalsIgnoreCase(args[0])) {
                return switch (args[1].toLowerCase()) {
                    case "runner", "hunter", "spectator", "clear" -> playerSubCommandFilter(sender, args[args.length - 1]);
                    default -> new ArrayList<>();
                };
            }
        }
        return new ArrayList<>();
    }

    public void sendUsage(CommandSender sender) {
        sender.sendMessage(MessageUtils.parseColor("""
                &7[&a?&7]&b用法: &e/manhunt(mh) arena <create/delete/recreate>
                &e/manhunt(mh) jointeam <runner/hunter/spectator/clear> <玩家...>
                &e/manhunt(mh) clearteam
                &e/manhunt(mh) tpworld <runner/hunter/spectator/null/*(all)> <世界>
                &e/manhunt(mh) ondead <hunter/runner> <选项>
                &e/manhunt(mh) timer <start/stop/*(时间·秒)>
                &e/manhunt(mh) start <猎人延迟出动时间>
                &e/manhunt(mh) reload
                &e/manhunt(mh) randomrunner""")); // 1
    }

    private void createArena(CommandSender executor) {
        Bukkit.broadcastMessage(MessageUtils.parseColor("&7[&b!&7]&b世界正在生成中 服务器可能会卡顿一段时间..."));
        Manhunt.getWorldManager().createArena();
        executor.sendMessage(MessageUtils.parseColor("&7[&b!&7]&b竞技场创建完毕"));
    }
    private void deleteArena(Runnable afterDone) {
        Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "advancement revoke @a everything");
        Manhunt.getWorldManager().deleteArena(afterDone);
    }
    private Set<Player> parseTpWorldPlayer(String arg) {
        switch (arg.toLowerCase()) {
            case "runner":
                return Manhunt.getTeamManager().getRunners();
            case "hunter":
                return Manhunt.getTeamManager().getHunters();
            case "spectator":
                return Manhunt.getTeamManager().getSpectator();
            case "null":
                Set<Player> var_3_b = new HashSet<>();
                Bukkit.getOnlinePlayers().forEach(p -> {
                    if (Manhunt.getTeamManager().getPlayerTeam(p) == null) var_3_b.add(p);
                });
                return var_3_b;
            case "*":
            case "all":
                return new HashSet<>(Bukkit.getOnlinePlayers());
            default:
                Player player = Bukkit.getPlayer(arg);
                if (player == null) return null;
                Set<Player> var1 = new HashSet<>();
                var1.add(player);
                return var1;
        }
    }
    private void joinTeam(CommandSender executor, String team, String[] players) {
        if (checkPermission(executor, "manhunt.jointeam")) return;
        Set<Player> playerSet = new HashSet<>();
        for (String player : players) {
            Player p = Bukkit.getPlayer(player);
            if (p == null) {
                executor.sendMessage(MessageUtils.parseColor("&7[&c×&7]&c未找到玩家 &e") + player);
                continue;
            }
            playerSet.add(p);
        }
        if (playerSet.size() == 0) return;
        ITeamManager teamManager = Manhunt.getTeamManager();
        switch (team.toLowerCase()) {
            case "runner" -> playerSet.forEach(p -> teamManager.setPlayerTeam(p, PlayerTeam.RUNNER));
            case "hunter" -> playerSet.forEach(p -> teamManager.setPlayerTeam(p, PlayerTeam.HUNTER));
            case "spectator" -> playerSet.forEach(p -> teamManager.setPlayerTeam(p, PlayerTeam.SPECTATOR));
            case "clear" -> playerSet.forEach(p -> teamManager.setPlayerTeam(p, null));
            default -> executor.sendMessage(MessageUtils.parseColor("&7[&c×&7]&c未知的阵营 &e") + team);
        }
    }
}
